﻿/// Author:					Walter Ferrari
/// Created:				2010-01-18
/// ref:                    http://www.snello.it
/// The use and distribution terms for this software are covered by the 
/// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)  
/// By using this software in any fashion, you are agreeing to be bound by 
/// the terms of this license.
///
/// You must not remove this notice, or any other, from this software.
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Globalization;

namespace InteractChartCommonLib
{
    public enum PairSortMethod
    { First = 0, Second = 1 };


    public static class ComparerHelper
    {
        public static int PairComparison(object aObj, object bObj)
        {
            if (aObj.GetType()!= bObj.GetType())
            {
                throw new ArgumentException("two different objects are not comparable");
            }

            double aDbl, bDbl;
            if (TryConvertToDouble(aObj, out aDbl) && TryConvertToDouble(bObj, out bDbl))
            {
                return aDbl.CompareTo(bDbl);
            }
            else if(aObj is string)
            {
                return ((aObj as string).CompareTo(bObj as string));
            }
            return 0;

        }

        /// <summary>
        /// Attempts to convert an object into a double.
        /// </summary>
        /// <param name="value">The value to convert.</param>
        /// <param name="doubleValue">The double value.</param>
        /// <returns>A value indicating whether the value can be converted to a 
        /// double.</returns>
        public static bool TryConvertToDouble(object value, out double doubleValue)
        {
            doubleValue = default(double);
            try
            {
                if (value != null &&
                    (value is double
                    || value is int
                    || value is byte
                    || value is short
                    || value is decimal
                    || value is float
                    || value is long
                    || value is uint
                    || value is sbyte
                    || value is ushort
                    || value is ulong
                    || value is string ))
                {
                    doubleValue = ComparerHelper.ToDouble(value);
                    return true;
                }
                
            }
            catch (FormatException)
            {
            }
            catch (InvalidCastException)
            {
            }

            
            return false;
        }

        /// <summary>
        /// Converts an object into a double.
        /// </summary>
        /// <param name="value">The value to convert to a double.</param>
        /// <returns>The converted double value.</returns>
        public static double ToDouble(object value)
        {
            return Convert.ToDouble(value, CultureInfo.InvariantCulture);
        }


    }
    

    public class Pair : INotifyPropertyChanged,  IComparable
    {

        private object _first;
        private object _second;
        private static PairSortMethod _sortOrder;


        /// <summary>
        /// Gets or sets the first value.
        /// </summary>
        public object First
        {
            get
            {
                return _first;
            }
            set
            {
                _first = value;
                OnPropertyChanged("First");
            }
        }

        /// <summary>
        /// Gets or sets the second value.
        /// </summary>
        public object Second
        {
            get
            {
                return _second;
            }
            set
            {
                _second = value;
                OnPropertyChanged("Second");
            }
        }


        /// <summary>
        /// Implements the INotifyPropertyChanged interface.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Fires the PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">Name of the property that changed.</param>
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public static PairSortMethod SortOrder
        {
            get { return _sortOrder; }
            set { _sortOrder = value; }
        }

             
        int IComparable.CompareTo(object obj)
        {
            if (obj is Pair)
            {
                Pair p2 = (Pair)obj;


                return ((Double)First).CompareTo(p2.First) + ComparerHelper.PairComparison(Second, p2.Second);
                /*
                switch (_sortOrder)
                {
                    case PairSortMethod.First:
                        return ComparerHelper.PairComparison(First,p2.First);
                    case PairSortMethod.Second:
                        return ComparerHelper.PairComparison(Second,p2.Second);;
                    default:
                        return ((Double)First).CompareTo(p2.First);
                }
                 */ 
            }
            else
                throw new ArgumentException("Object is not a Pair.");
            
        }


    }

    
}
